<template>
  <!--https://fullcalendar.io/-->
  <div class="calendar-container">
    <FullCalendar ref="fullCalendar" :options="calendarOptions" />
    <el-dialog
      :visible.sync="addEventDialogVisible"
      :before-close="handleAddEventClose"
      title="新增日程"
      width="900px"
      :append-to-body="true"
      :close-on-click-modal="false"
      :close-on-press-escape="true">
      <el-form ref="addEventForm" :rules="addEventRules" :model="addEventRecord" label-position="right" label-width="120px">
        <el-form-item label="标题:" prop="title">
          <el-input v-model="addEventRecord.title" maxlength="20" show-word-limit placeholder="请输入标题" />
        </el-form-item>
        <el-form-item label="类型:" prop="type">
          <el-select v-model="addEventRecord.type" style="width:100%">
            <el-option label="日程记录" value="1" />
            <el-option label="规划" value="2" />
          </el-select>
        </el-form-item>
        <el-form-item label="状态:" prop="status">
          <el-select v-model="addEventRecord.status" style="width:100%">
            <el-option label="计划中" value="1" />
            <el-option label="一开始" value="2" />
            <el-option label="已结束" value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="颜色:" prop="color">
          <el-color-picker v-model="addEventRecord.color" />
        </el-form-item>
        <el-form-item label="全天:" prop="allDay">
          <el-switch v-model="addEventRecord.allDay" />
        </el-form-item>
        <el-row>
          <el-col :span="12">
            <el-form-item label="开始:" prop="start">
              <el-date-picker
                v-model="addEventRecord.start"
                :type="true===addEventRecord.allDay?'date':'datetime'"
                :format="true===addEventRecord.allDay?'yyyy-MM-dd':'yyyy-MM-dd HH:mm'"
                value-format="timestamp"
                placeholder="请选择开始时间" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="结束:" prop="end">
              <el-date-picker
                v-model="addEventRecord.end"
                :type="true===addEventRecord.allDay?'date':'datetime'"
                :format="true===addEventRecord.allDay?'yyyy-MM-dd':'yyyy-MM-dd HH:mm'"
                value-format="timestamp"
                placeholder="请选择结束时间" />
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="备注:" prop="remark">
          <el-input v-model="addEventRecord.remark" :rows="4" type="textarea" maxlength="300" show-word-limit />
        </el-form-item>
      </el-form>
      <span slot="footer">
        <el-button @click="handleAddEventCancel">取 消</el-button>
        <el-button type="primary" @click="handleAddEventSave">保 存</el-button>

      </span>
    </el-dialog>
  </div>
</template>
<script>
import FullCalendar from '@fullcalendar/vue'
import multiMonthPlugin from '@fullcalendar/multimonth' // 年视图
import dayGridPlugin from '@fullcalendar/daygrid'// 月视图
import timeGridPlugin from '@fullcalendar/timegrid'// 天视图、周视图

import interactionPlugin from '@fullcalendar/interaction'
import moment from 'moment'
import CalendarExample from './calendar'

export default {
  components: { FullCalendar },
  props: {
    height: {
      type: String,
      default: '100%' // auto 100% **px
    },
    headerToolbar: {
      type: Object,
      default: () => {
        return {
          start: 'today addEvent',
          center: 'title',
          end: 'customPrevYear,customPrev,customNext,customNextYear multiMonthYear,dayGridMonth,timeGridWeek,timeGridDay,timeGridFourDay'
        }
      }
    },
    initialView: {
      type: String,
      default: 'dayGridMonth' // dayGridMonth multiMonthYear  timeGridWeek  timeGridDay timeGridFourDay
    },
    lunarShow: {
      type: Boolean,
      default: true
    }
  },
  data() {
    var validateEnd = (rule, value, callback) => {
      if (value === this.addEventRecord.start) {
        callback(new Error('开始时间与结束时间不能一致!'))
      } else if (value < this.addEventRecord.start) {
        callback(new Error('结束时间不能小于开始时间!'))
      } else {
        callback()
      }
    }
    return {
      calendarApi: null,
      calendarOptions: {
        height: this.height,
        plugins: [multiMonthPlugin, dayGridPlugin, timeGridPlugin, interactionPlugin],
        initialView: this.initialView,
        selectable: true,
        dateClick: this.handleDateClick,
        select: this.handleDateSelect,
        eventClick: this.handleEventClick,
        locale: 'zh-cn',
        buttonText: {
          today: '今天',
          multiMonthYear: '年',
          dayGridMonth: '月',
          timeGridWeek: '周',
          timeGridDay: '日'
        },
        allDayText: '全天',
        headerToolbar: this.headerToolbar,
        views: {
          timeGridFourDay: {
            type: 'timeGrid',
            duration: { days: 4 },
            buttonText: '4 天'
          },
          dayGridMonth: {
            displayEventTime: false,
            dayCellContent: (item) => {
              if (this.lunarShow === true) {
                const solar = CalendarExample.Solar.fromDate(item.date)
                var lunar = solar.getLunar()
                var holiday = CalendarExample.HolidayUtil.getHoliday(moment(item.date).format('YYYY-MM-DD'))
                var holidayName = null
                if (holiday) {
                  if (holiday.isWork() === false) {
                    holidayName = holiday.getName()
                  }
                } else {
                  var festivals = solar.getFestivals().concat(lunar.getFestivals()).concat(lunar.getOtherFestivals())
                  holidayName = festivals.join('、')
                }
                return { html: `
                <div>${solar.getDay()}</div>
                <div style='font-weight: normal; font-size: 12px; margin-top: 2px;'>
                  ${holidayName ? '<span style="font-weight: bold;" title=' + holidayName + '>' + holidayName + '</span>' : solar.getLunar().getDayInChinese()}
                </div>`
                }
              } else {
                return moment(item.date).format('D')
              }
            }
          }
        },
        customButtons: {
          addEvent: {
            text: '新增日程',
            click: () => {
              this.handleAddEvent()
            }
          },
          customPrevYear: {
            text: '<<',
            hint: '上一年',
            click: () => {
              this.$refs.fullCalendar.getApi().prevYear()
              this.handlechangeTime('year')
            }
          },
          customNextYear: {
            text: '>>',
            hint: '下一年',
            click: () => {
              this.$refs.fullCalendar.getApi().nextYear()
              this.handlechangeTime('year')
            }
          },
          customPrev: {
            text: '<',
            hint: '上一个月',
            click: () => {
              this.$refs.fullCalendar.getApi().prev()
              this.handlechangeTime('month')
            }
          },
          customNext: {
            text: '>',
            hint: '下一个月',
            click: () => {
              this.$refs.fullCalendar.getApi().next()
              this.handlechangeTime('month')
            }
          }
        },
        events: []
      },
      addEventDialogVisible: false,
      defaultEventStart: new Date().getTime(),
      defaultEventEnd: new Date().getTime(),
      addEventRecord: {},
      addEventRules: {
        title: [
          { required: true, message: '请输入标题', trigger: 'blur' }
        ],
        start: [
          { required: true, message: '请选择开始时间', trigger: 'blur' }
        ],
        end: [
          { required: true, message: '请选择结束时间', trigger: 'blur' },
          { validator: validateEnd, trigger: 'blur' }
        ],
        color: [
          { required: true, message: '请选择颜色', trigger: 'blur' }
        ]
      }
    }
  },
  created() {
    console.log('dashboard')
  },
  mounted() {
    this.calendarApi = this.$refs.fullCalendar.getApi()
    this.$emit('getLunar', CalendarExample)
    this.$emit('getCalendarApi', this.calendarApi)
  },
  methods: {
    updateOptions(options) {
      Object.assign(this.calendarOptions, options)
      this.calendarApi.refetchEvents() // 如果更新了事件源，需要刷新事件
    },
    handlechangeTime(type) {
      var currentDate = this.$refs.fullCalendar.getApi().currentData.currentDate
      var start = moment(currentDate).startOf(type).format('YYYY-MM-DD 00:00:00')
      var end = moment(currentDate).endOf(type).format('YYYY-MM-DD 23:59:59')
      this.$emit('changeTime', {
        date: currentDate.getTime(),
        dateStr: moment(currentDate).format('YYYY-MM-DD hh:mm:ss'),
        start: new Date(start).getTime(),
        startStr: start,
        end: new Date(end).getTime(),
        endStr: end,
        type: type
      })
    },
    handleDateClick(arg) {
      this.$emit('dateClick', {
        dateStr: arg.dateStr,
        date: arg.date.getTime()
      })
    },
    handleDateSelect(arg) {
      this.$emit('dateSelect', {
        startStr: arg.startStr,
        endStr: arg.endStr,
        start: arg.start.getTime(),
        end: arg.end.getTime()
      })
      this.defaultEventStart = arg.start.getTime()
      this.defaultEventEnd = arg.start.getTime()
    },
    handleEventClick(arg) {
      this.$emit('eventClick', arg.event)
    },
    /**
     * 添加单个事件
     * 事件属性参考：https://fullcalendar.io/docs/event-object
     */
    addEvent(event) {
      if (!event) {
        this.$message.warning('事件不能为空！')
        return
      }
      this.addEvents([event])
    },
    /**
     * 添加多个事件
     */
    addEvents(events) {
      if (!events) {
        this.$message.warning('事件不能为空！')
        return
      }
      if (events.length === 0) {
        this.$message.warning('事件不能为空！')
        return
      }
      events.forEach(item => {
        this.calendarApi.addEvent(item)
      })
    },
    handleAddEvent() {
      this.addEventDialogVisible = true
      this.addEventRecord = {
        type: '1',
        status: '1',
        color: '#4a5dff',
        allDay: false,
        start: this.defaultEventStart,
        end: this.defaultEventEnd + 1 * 60 * 60 * 1000
      }
      this.$nextTick(() => {
        this.$refs['addEventForm'].clearValidate()
      })
    },
    handleAddEventClose(done) {
      this.$confirm('确认关闭?').then(_ => {
        done()
        this.handleAddEventCancel()
      }).catch(_ => {})
    },
    handleAddEventCancel() {
      this.addEventDialogVisible = false
    },
    handleAddEventSave() {
      this.$refs['addEventForm'].validate(valid => {
        if (valid) {
          this.$emit('addEvent', this.addEventRecord)
        }
      })
    }
  }
}
</script>
<style  lang="scss">
  @import "./index.scss";
</style>

